package pms.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import pms.om.Jahr;
import pms.om.Feiertag;
import pms.om.Sperrtag;
import pms.om.Urlaubsanspruch;

public class JahrDao extends HibernateDaoSupport	{
	
	/**
	 * R&uuml;ckgabe eines {@link Jahr} anhand der Id
	 * @param id
	 * @return ausgew&auml;hltes Jahr
	 */

	public Jahr findById(int id) {
		HibernateTemplate template = getHibernateTemplate();
		return (Jahr) template.get(Jahr.class, id);
	}
		
	/**
	 * L&ouml;schen des ausgew&auml;hlten Jahres
	 * @param id
	 */

	public boolean deleteById(int id) {
		HibernateTemplate template = getHibernateTemplate();
		boolean result = false;
		Jahr j = findById(id); 
		if ((j.getFeiertageimdefiniertenjahr().isEmpty()) && (j.getSperrtageimdefiniertenjahr().isEmpty())) {
			template.delete(j);    // nur löschen wenn dem Jahr noch keine Sperr- und Feiertage zugeordnet
			template.flush();
			result = true;
		}
		return result;
	}
					
	/**
	 * R&uuml;ckgabe aller Jahre
	 * @return alle Jahre
	 */

	@SuppressWarnings("unchecked")
	public Set<Jahr> findAll() {
		HibernateTemplate template = getHibernateTemplate();
		List<Jahr> allejahre = template.loadAll(Jahr.class);
		Set<Jahr> results = new HashSet<Jahr>();
		for (Jahr jahr : allejahre) {
			results.add(jahr);
		}
		return results;
	}

			    
	/**
	 * Anlegen eines neuen Jahres
	 * @param jahr
	 */

	public void create(String jahr) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = new Jahr(jahr);
		template.persist(j);
	}

	/**
	 * &Auml;ndern des Jahres anhand der ausgew&auml;hlten Id auf die neuen 
	 * &uuml;bergebenen Eigenschaften
	 * @param id
	 * @param jahr
	 */
	
	public void modify(int id, String jahr) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = (Jahr) template.get(Jahr.class, id);
		j.setJahr(jahr);
		template.saveOrUpdate(j);
		template.flush();
	}
	
	/**
	 * R&uuml;ckgabe aller Feiertage des Jahres mit der id = idj
	 * @param idj
	 * @return alle Feiertage des ausgew&auml;hlten Jahres
	 */

	public Set<Feiertag> findeallefeiertagediezugeordnet(int idj) {
		return findById(idj).getFeiertageimdefiniertenjahr();
	}
	
	/**
	 * R&uuml;ckgabe aller Sperrtage des Jahres mit der id = idj
	 * @param idj
	 * @return alle Sperrtage des ausgew&auml;hlten Jahres
	 */	

	public Set<Sperrtag> findeallesperrtagediezugeordnet(int idj) {
		return findById(idj).getSperrtageimdefiniertenjahr();
	}
	
	/**
	 * Gibt die Id eines Jahres zur&uuml;ck, wenn Jahreszahl &uuml;bergeben wird
	 * @param imjahr
	 */	

	private int getIdJahr(int imjahr) {
		int result = 0;
		for (Jahr j : findAll()) {
			if (Integer.parseInt(j.getJahr()) == imjahr) {
				result = j.getId();
			}
		}
		return result;
	}
	
	/**
	 * Gibt die Feiertage, die dem Jahr mit der ausgew&auml;hlten Jahreszahl
	 * zugeordnet sind, zur&uuml;ck
	 * @param imjahr
	 * @return Alle Feiertage, die schon zugeordnet sind
	 */	

	public Set<Feiertag> findeallefeiertagediezugeordnetmitjahreszahl(int imjahr) {
		int i = getIdJahr(imjahr);
		return findeallefeiertagediezugeordnet(i);
	}
	
	/**
	 * Gibt alle Sperrtage die dem Jahr mit der id = idj zugeordnet sind, zur&uuml;ck
	 * @param imjahr
	 * @return Alle Sperrtage, die schon zugeordnet sind
	 */	

	public Set<Sperrtag> findeallesperrtagediezugeordnetmitjahreszahl(int imjahr) {
		int i = getIdJahr(imjahr);
		return findeallesperrtagediezugeordnet(i);
	}
	
	/**
	 * L&ouml;sche einen Feiertag mit der id =idf aus dem Jahr 
	 * mit der id =idj
	 * @param idj
	 * @param idf
	 */

	public void deleteverknuepfungfeiertagzujahr(int idj, int idf) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = (Jahr) template.get(Jahr.class, idj);
		Feiertag f = (Feiertag) template.get(Feiertag.class, idf);
		j.loescheFeiertag(f);
		template.saveOrUpdate(j);
		template.flush();
	}
		
	/**
	 * F&uuml;ge einen Feiertag mit der id =idf dem Jahr mit der id =idj zu	
	 * @param idj
	 * @param idf
	 */

	public void createverknuepfungfeiertagzujahr(int idj, int idf) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = (Jahr) template.get(Jahr.class, idj);
		Feiertag f = (Feiertag) template.get(Feiertag.class, idf);
		j.fuegeFeiertaghinzu(f);
		template.saveOrUpdate(j);
		template.flush();
	}

	/**
	 * L&ouml;sche einen Sperrtag mit der id =idf aus dem Jahr mit der id =idj
	 * @param idj
	 * @param ids
	 */

	public void deleteverknuepfungsperrtagzujahr(int idj, int ids) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = (Jahr) template.get(Jahr.class, idj);
		Sperrtag s = (Sperrtag) template.get(Sperrtag.class, ids);
		j.loescheSperrtag(s);
		template.saveOrUpdate(j);
		template.flush();
	}

	/**
	 * F&uuml;ge einen Sperrtag mit der id =ids dem Jahr mit der id =idj zu	
	 * @param idj
	 * @param ids
	 */

	public void createverknuepfungsperrtagzujahr(int idj, int ids) {
		HibernateTemplate template = getHibernateTemplate();
		Jahr j = (Jahr) template.get(Jahr.class, idj);
		Sperrtag s = (Sperrtag) template.get(Sperrtag.class, ids);
		j.fuegeSperrtaghinzu(s);
		template.saveOrUpdate(j);
		template.flush();	
	}
	
	/**
	 * R&uuml;ckgabe aller Jahre die vorhanden sind, außer denen, die im
	 * Urlaubsset vorhanden sind
	 */

	public Set<Jahr> findeRestJahre(Set<Urlaubsanspruch> urlaubsansprueche) {
		// alle Jahre in jahrevonurlaubsansprueche sammeln die im set urlaubsansprueche vorkommen
		Set<Jahr> jahrevonurlaubsansprueche = new HashSet<Jahr>();
		for (Urlaubsanspruch uspruch : urlaubsansprueche) {
			jahrevonurlaubsansprueche.add(uspruch.getJahr());
		}
		Set<Jahr> jahreresult = findAll();
		for (Jahr jahr : jahrevonurlaubsansprueche) {
			jahreresult = findAllbisaufEinen(jahr, jahreresult);
		}
		return jahreresult;
	}
	
	
	/** 
	 * R&uuml;ckgabe des Set weniger des Jahres j
	 * @return Finde alle bis auf einen
	 */

	private Set<Jahr> findAllbisaufEinen(Jahr j, Set<Jahr> jahreresult) {
		Set<Jahr> result = new HashSet<Jahr>();
    	for (Jahr jahr : jahreresult) {
    		if (!jahr.equals(j)) {
    			result.add(jahr);
    		}	 
    	}
		return result;
	}

	/**
	 * Jahr > 0 dann true oder false und wenn nicht doppelt
	 * @param jahrzupruefen
	 */

	public boolean pruefeJahr(int jahrzupruefen) {
		boolean result = false;
		for (Jahr jahr : findAll()) {
			if (Integer.parseInt(jahr.getJahr()) == jahrzupruefen) {
				result = false;
			} else {
				result = true;
			}
		}
		if (jahrzupruefen > 0) { 
			result = true;
		} else {
			result = false;
		}
		System.out.println(result);
		return result;
	}
	
}
